package edu.cicese.alz.temporal;

import edu.cicese.alz.NFCActivity;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by: Eduardo Quintana Contreras
 * Date: 6/06/12
 * Time: 02:47 PM
 */
public class AudioFilesSorter {

	private static String[] NFCs = new String[]{
			NFCActivity.HACER_CAMA,
			NFCActivity.BAÑARSE,
			NFCActivity.ASEO_PERSONAL,
			NFCActivity.LAVARSE_DIENTES,
			NFCActivity.VESTIRSE,
			NFCActivity.BAÑO,
			NFCActivity.PREPARAR_COMIDA,
			NFCActivity.COMER,
			NFCActivity.VER_TELEVISION,
			NFCActivity.HABLAR_TELEFONO};

	public static void sortAudioFiles() {
		String userPath = "D:\\_proyectoAlz\\data\\users\\incense";
		String audioDir = "D:\\_proyectoAlz\\data\\sorted_audio\\";
		long minTS, maxTS;
		boolean nfcTagFound;
		Map<Integer, Integer> nfcCounter = new HashMap();

//		int[] nfcCounter = new int[NFCs.length];

		for (int user = 1; user <= 15; user++) {
			for (String nfc : NFCs) {
				nfcCounter.put(NFCActivity.getMessageID(nfc), 0);
			}
			
			ArrayList<AudioFile> audioFiles = getAudioList(userPath + user);

			new File(audioDir + user).mkdirs();

			for (String nfc : NFCs) {
				new File(audioDir + user + "\\" + nfc).mkdirs();
			}

			ArrayList<NFCTag> nfcTags = getSpecificNFC(user);

			for (AudioFile audioFile : audioFiles) {
				nfcTagFound = false;
				minTS = audioFile.timestamp - 20000;
				maxTS = audioFile.timestamp + 20000;
				for (NFCTag nfcTag : nfcTags) {
					if (nfcTag.timestamp > minTS && nfcTag.timestamp < maxTS && nfcCounter.get(nfcTag.tagID) < 8) {
						nfcTagFound = true;
						copyFile(audioFile.path, audioDir + user + "\\" + NFCActivity.activities[nfcTag.tagID - 1] + "\\" + audioFile.name);
						nfcCounter.put(nfcTag.tagID, nfcCounter.get(nfcTag.tagID) + 1);
						break;
//						System.out.println(audioFile.timestamp + " Found. ID: " + nfcTag.tagID);
					}
					if (nfcTag.timestamp > maxTS) {
						break;
					}
				}
				if (!nfcTagFound) {
					System.out.println(audioFile.timestamp + " Not found.");
				}
			}
		}
	}

	public static ArrayList<AudioFile> getAudioList(String userPath) {
		ArrayList<AudioFile> audioFiles = new ArrayList<>();

		File userDir = new File(userPath);
		FileFilter dirFilter = new FileFilter() {
			public boolean accept(File file) {
				return file.isDirectory();
			}
		};
		File[] dirs = userDir.listFiles(dirFilter);
		for (File dir : dirs) {
			FilenameFilter filenameFilter = new FilenameFilter() {
				public boolean accept(File dir, String name) {
					return name.toLowerCase().endsWith(".raw");
				}
			};
			File[] files = dir.listFiles(filenameFilter);
			if (files != null) {
				for (File file : files) {
					try {
						audioFiles.add(new AudioFile(file.getCanonicalPath(), file.getName()));
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}

		return audioFiles;
	}

	public static ArrayList<NFCTag> getSpecificNFC(int userID) {
		ArrayList<NFCTag> NFCTags = new ArrayList<>();
		Connection connection;
		Statement statement;
		ResultSet resultSet;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			connection = DriverManager.getConnection("jdbc:mysql://localhost/alzheimerdb", "root", "alz");
			statement = connection.createStatement();

			resultSet = statement.executeQuery(querySpecificNFC(userID));

			NFCTags = new ArrayList<>();
			while (resultSet.next()) {
				NFCTags.add(new NFCTag(resultSet.getInt(1), resultSet.getLong(2)));
			}

		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		}

		return NFCTags;
	}

	public static String querySpecificNFC(int userID) {
		String query = "SELECT MESSAGE_ID, TIMESTAMP FROM nfc WHERE USER_ID = " + userID + " AND MESSAGE_ID IN (";
		int c = 0;
		for (String ss : NFCs) {
			query += NFCActivity.getMessageID(ss);
			if (++c < NFCs.length) {
				query += ", ";
			}
			else {
				query += ");";
			}
		}
		System.out.println(query);
		return query;
	}

	//! Copies the recorded audio to a file inside the tag directory
	public static void copyFile(String currentFilename, String newFilename) {
		File currentFile = new File(currentFilename);
		File newFile = new File(newFilename);

		if (currentFile.exists()) {
			try {
				FileInputStream in = new FileInputStream(currentFile);
				FileOutputStream out = new FileOutputStream(newFile);

				byte[] buffer = new byte[4096];
				int bytesRead;
				while ((bytesRead = in.read(buffer)) > 0){
					out.write(buffer, 0, bytesRead);
				}
				in.close();
				out.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

			System.out.println("File copied. (" + newFilename + ")");
		}
		else {
			System.out.println("File missing.");
		}
	}

	public static void main(String[] a) {
		sortAudioFiles();
	}


	static class AudioFile {
		public String path, name;
		public long timestamp;
		public boolean found = false;
		public int nfcID;

		public AudioFile (String path, String name) {
			this.path = path;
			this.name = name;
			this.timestamp = Long.parseLong(name.substring(14, 27));
		}
	}

	static class NFCTag {
		public int tagID;
		public long timestamp;

		public NFCTag(int tagID, long timestamp) {
			this.tagID = tagID;
			this.timestamp = timestamp;
		}
	}
}
